home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c++ / 1015 < prev    next >
Encoding:
Text File  |  1996-08-06  |  8.2 KB  |  194 lines

  1. Path: fido.asd.sgi.com!austern
  2. From: Philippe Verdy <100105.3120@compuserve.com>
  3. Newsgroups: comp.std.c++
  4. Subject: Re: Must exception classes have copy constructors?
  5. Date: 09 Apr 1996 09:58:00 PDT
  6. Organization: CompuServe Incorporated
  7. Approved: austern@isolde.mti.sgi.com
  8. Message-ID: <4kca45$347@dub-news-svc-5.compuserve.com>
  9. NNTP-Posting-Host: isolde.mti.sgi.com
  10. X-Original-Date: 9 Apr 1996 00:13:57 GMT
  11. X-Auth: PGPMoose V1.1 PGP comp.std.c++
  12.     iQBVAwUBMWqXGky4NqrwXLNJAQHcRAIAkIZK0gRgssBg1FMdnq9TmvBO2ouCX2mq
  13.     tuEJSUX5i7kcGok400FDb0Povo2/m/4+JamjHv6Jwu9f75C/sy9d7Q==
  14.     =n9UE
  15. Originator: austern@isolde.mti.sgi.com
  16.  
  17. David Byrden <Goyra@iol.ie> s'Θcrit :
  18. > Alan Griffiths <aGriffiths@ma.ccngroup.com> wrote:
  19. > >Looking through the DWP I can't see any reason to require a copy 
  20. > >constructor, but there are references to copying temporaries.
  21. >           What DWP did you read? The January 96 version requires that the 
  22. > "throw" statement have access to the copy constructor and destructor of a 
  23. > thrown object.
  24.           I have submitted an article which has been rejected
  25. (I don't know why) about copy constructors needed. What I meant
  26. is such a restriction about the copy constructor is only to
  27. allow cleaner exception handling, concerning stack unrolling.
  28. In effect, if the compiler dis not have access to the copy
  29. constructor, the exception catcher which effectively matches
  30. the exception in the current context should be limited to
  31. use references only on the object.
  32.  
  33. Because an error catcher can catch only a base class of the
  34. thrown object, and not the full object, when the exception
  35. matches, the thrown object will have to be copied to a catcher
  36. variable which may have less members than the original thrown
  37. object. This copy will occur while the throwing function con-
  38. text is still active, because the original thrown object was
  39. constructed within the thrower and may still reference some
  40. fields which will be destructed by the stack unrolling algo-
  41. rithm once the catcher receives the focus to do the appro-
  42. priate action the handler require.
  43.  
  44. The reason why I am putting this submission is that I don't
  45. know why this scheme does not allow resumable exceptions:
  46. after all, when an assertion fails in a function which has
  47. to throw an exception, it first constructs an exception object
  48. within its context, then calls a library function to perform
  49. the exception matching. Once the matching is found, this
  50. library first call the exception handler to perform the
  51. copy constructor to a temporary object with type equal to
  52. the one taken by the catcher. Then only the library returns
  53. to the exception thrower, which will perform sannity in its
  54. context, and return to its caller in exception state (may be
  55. by returning an extra flag in a register, or by modifying
  56. its return address to an laternate return address given by
  57. its caller, so that the caller can continue stack unrolling
  58. on its active block and eventually jump to the catcher block
  59. if the calling block was a try { } block.
  60.  
  61. So if the catcher has temporarily access to the thrower's
  62. context which is still valid, I think that exceptions can
  63. be resumed:
  64. instead of just performing the copy contructor of the 
  65. catched exception, the library could first enter into a
  66. status function whose execution will say if the exception
  67. can be recovered or not. If it cannot, this context can be
  68. chained to other pending resumable catchers, until one of
  69. them return a status that says the exception can be resumed.
  70.  
  71. If no resumable catcher is found in this chain, then the
  72. library will return a "don't-resume" status to the thrower
  73. which will effectively destroy its own exception object, then
  74. will start the stack unrolling for an effective exception.
  75.  
  76. But if a catcher returns a "resume" status, this status can
  77. be immediately returned to the thrower, which will continue
  78. as if the exception had not occured.
  79.  
  80. This has several impacts on the code specification, because
  81. the programmer should have to specify whever its throw()
  82. invocation could resume or not. So this requires an additional
  83. keyword like throw_resumable(), which does not have the "goto"
  84. or "break" or "continue" or "return" semantics, in the fact
  85. that the exception is not fatal (the jump is conditional).
  86. The compiler would generate a different library call for this
  87. addtional operator.
  88.  
  89. By the same way, a resumable error catcher could fail to find
  90. a way which will satisfy the resume condition indicated by
  91. the exception object. But there could be other resumable
  92. catchers pending. This gives the opportunity of the resumable
  93. exception catchers chain (this only adds a unique static code
  94. pointer in each execution thread). The rest of the storage for
  95. this chain can be allocated at the catch point.
  96.  
  97. Finally, resumable exception handlers must indicate that they
  98. can resume the exception. The semantics of the standard 
  99. catch() construct is not sufficient for it as the catcher code
  100. to execute is not od the same kind: a standard catch()
  101. handler executes its code once the exception has occured, in a
  102. constext where the thrower does not exists any more.
  103. So this requires another keyword or construction like
  104. catch_resumable() instead of catch().
  105.  
  106. For this new construction, the copy constructor does not have
  107. to be invoked, because the thrower context is still valid, so
  108. a catch_resumable() handler can receive directly a reference
  109. to the thrown object. The code in that catcher must be quite
  110. short if the exception kind is a lack of resource, because
  111. the thrower context is still active.
  112.  
  113. In order to indicate its intention of resuming the exception,
  114. this code should use a specific construct (for example: retry;
  115. without parameters, which means "cancel the pending exception
  116. and resume to the resumable thrower"). This would make the
  117. resumable catcher return a "resume" state to the exception
  118. library which will be reported to the thrower. In that case
  119. all it would have to do is just delete its temporary thrown
  120. object and continue the execution.
  121.  
  122. Such resumable exceptions should be very useful for time-out
  123. exceptions, or device-not-ready exceptions (which may be
  124. resumed after the user has been noticed of it by an alert
  125. with choices like "Retry" or "Cancel"), or for exceptions
  126. caused by lack of resources (a resumable exception catcher
  127. could check if it can free up some of the resources indicated
  128. by the exception object, for example it could free up some
  129. unused cache-buffers to allow more memory for the thrower).
  130.  
  131. This model has no-impact on the existing code, and will add
  132. overhead only when new keywords are in actions. All other
  133. semantics of stancard throw()/catch() pairs are preserved.
  134. What do you think of this model ?
  135.  
  136. Example of resumable exceptions for out-of-memory:
  137. --------------
  138. in the catcher
  139. --------------
  140. struct OutOfMemory; // fatal exception
  141. struct NeedMemory
  142. : public OutOfMemory // resumable exception
  143. {
  144.   NeedMemory(size_t size) : OutOfMemory(size) {}
  145. }
  146. ...
  147. try {
  148.   ...
  149.   function() // this can send a resumable exception
  150.   ...
  151. }
  152. catch_resumable(NeedMemory &exc) {
  153.   // check if can free up some memory for exc.size()
  154.   if (can_resume == true)
  155.     retry; // resume in the thrower
  156. } // cannot resume, check other catch_resumable() handlers now
  157. catch(OutOfMemory &exc) {
  158.   // Fatal exception, or resumable exception could not be
  159.   // resumed by an explicit use of "retry;" in any pending
  160.   // resumable_catchers.
  161.   // Make some cleanup required by this error.
  162. } // continue at end of try/catch construct
  163.  
  164. ----------------------------------
  165. Now in the exception thrower code:
  166. ----------------------------------
  167. void function()
  168. {
  169.    size_t size;
  170.    ...
  171.    int retries;
  172.    for (retries = 2; --retries >= 0) {
  173.      // needs some memory resource (size_t size)
  174.      ...
  175.      if (...can allocate size...)
  176.         break; // exits the for loop
  177.      if (retries == 0)
  178.         throw OutOfMemory(size); // fatal
  179.      throw_resumable NeedMemory(size);
  180.      // if could resume, continue here
  181.    } // retry loop
  182.    if (retries < 0)
  183.      throw OutOfMemory(size); // fatal
  184.    // OK, resource allocation succeeded
  185.    ...
  186. }
  187. ---
  188. [ comp.std.c++ is moderated.  To submit articles: Try just posting with your 
  189.                 newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  190.   comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  191.   Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  192.   Comments? mailto:std-c++-request@ncar.ucar.edu 
  193. ]
  194.